#include "uart.h"
#include "ui_uart.h"
#include <QDebug>
#include <QTimer>
#include <QMessageBox>
#include <QString>
#include <QFont>

UART::UART(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::UART),
    RequstData{0},
    m_portopenflag(0),
    m_TxNum(0),
    m_RxNum(0)
{
    ui->setupUi(this);
    ReadAvailablePort();
    init_MyCom();
}

UART::~UART()
{
    delete ui;
}

// 检测是否有可用串口
bool UART::ReadAvailablePort()
{
    foreach( const QSerialPortInfo &Info,QSerialPortInfo::availablePorts())//读取串口信息
        {
            qDebug() << "portName    :"  << Info.portName();//调试时可以看的串口信息
            qDebug() << "Description   :" << Info.description();
            qDebug() << "Manufacturer:" << Info.manufacturer();

            QSerialPort serial;
            serial.setPort(Info);

            if( serial.open( QIODevice::ReadWrite) )//如果串口是可以读写方式打开的
            {
                ui->comboBoxPortName->addItem( Info.portName() );//在comboBox那添加串口号
                serial.close();//然后自动关闭等待人为开启（通过那个打开串口的PushButton）
            }
             return true;
        }
    return false;
}

// 从串口缓冲区读取数据
void UART::readMyCom()
{

    RequstData = my_serialPort->readAll();// 用RequestData 存储串口接收到的数据
    QString buf;

    if(!RequstData.isEmpty())
    {
        if(ui->checkBoxHex->isChecked())// Hex 显示
        {
            for(int i = 0; i < RequstData.count(); i++)
            {
                QString s;
                s.sprintf("%02x  ", (unsigned char)RequstData.at(i));
                buf += s;
            }
            ui->textEdit->append(buf);
        }

        else
        {
            ui->textEdit->append(RequstData);// 正常显示
        }
    }

    m_RxNum += RequstData.size();

    qDebug() << RequstData;
    RequstData.clear();

    ui->lineEditTx->setText(QString::number(m_TxNum));
    ui->lineEditRx->setText(QString::number(m_RxNum));
}

// 初始化界面信息
void UART::init_MyCom()
{
    setWindowTitle("串口助手 V1.0");
    setWindowIcon(QIcon(":/image/image/1"));
    QFont font("Tahoma",12,50);// 宋体
    ui->textEdit->setFont(font);
    ui->textEdit->setReadOnly(true);
    ui->SendEdit->setFont(font);
}

void UART::SetCheckBit()
{
    if(ui->comboBoxCheckBit->currentText() == QString::fromLocal8Bit("无"))
    {
        my_serialPort->setParity( QSerialPort::NoParity );//校验，无
    }

    else if(ui->comboBoxCheckBit->currentText() == QString::fromLocal8Bit("奇校验"))
    {
        my_serialPort->setParity( QSerialPort::OddParity);//奇校验
    }

    else if(ui->comboBoxCheckBit->currentText() == QString::fromLocal8Bit("偶校验"))
    {
        my_serialPort->setParity( QSerialPort::EvenParity);//偶校验
    }
}

// 设置停止位
void UART::SetStopBit()
{
    if(ui->comboBoxStopBit->currentText() == "1")
    {
        my_serialPort->setStopBits( QSerialPort::OneStop );//一位停止位
    }

    else if(ui->comboBoxStopBit->currentText() == "1.5")
    {
        my_serialPort->setStopBits( QSerialPort::OneAndHalfStop );//1.5停止位
    }

    else if(ui->comboBoxStopBit->currentText() == "2")
    {
        my_serialPort->setStopBits( QSerialPort::TwoStop );//两位停止位
    }
}

// 设置数据流
void UART::SetDataFlow()
{
    if(ui->comboBoxData->currentText() == "off")
    {
        my_serialPort->setFlowControl(QSerialPort::NoFlowControl);// 不使用流控制
    }

    else if(ui->comboBoxData->currentText() == "hardware")
    {
        my_serialPort->setFlowControl(QSerialPort::HardwareControl);// 硬件流控制
    }

    else if(ui->comboBoxData->currentText() == "xonxoff")
    {
        my_serialPort->setFlowControl(QSerialPort::SoftwareControl);// 软件流控制
    }
}

// 设置数据位
void UART::SetDataBit()
{
    if(ui->comboBoxDataBit->currentText() == "8")
    {
        my_serialPort->setDataBits(QSerialPort::Data8);
    }

    else if(ui->comboBoxDataBit->currentText() == "7")
    {
        my_serialPort->setDataBits(QSerialPort::Data7);
    }

    else if(ui->comboBoxDataBit->currentText() == "6")
    {
        my_serialPort->setDataBits(QSerialPort::Data6);
    }

    else if(ui->comboBoxDataBit->currentText() == "5")
    {
        my_serialPort->setDataBits(QSerialPort::Data5);
    }
}

// 清空显示槽
void UART::on_ClearButton_clicked()
{
    ui->textEdit->clear();
}

// 发送按钮被按下
void UART::on_SendButton_clicked()
{
    if(1 == m_portopenflag)
    {
        my_serialPort->write(ui->SendEdit->text().toUtf8());// 将发送区接收到的数据存到缓冲区

        m_TxNum += ui->SendEdit->text().toUtf8().size();

        if(ui->checkBoxNewline->isChecked())// 加入回车换行
        {
           my_serialPort->write("\r\n");
           m_TxNum += 2;
        }
        qDebug() << "Ok" ;
    }

    else
    {
        QMessageBox::information(NULL,QString("Warning"),QString("串口未打开"));
    }
}


// 打开串口
void UART::on_OpenPortButton_clicked()
{
    if(ReadAvailablePort())
    {
        if(0 == m_portopenflag)
        {
            //对串口进行一些初始化
            my_serialPort = new QSerialPort(this);
            my_serialPort->setPortName( ui->comboBoxPortName->currentText() );
            my_serialPort->open( QIODevice::ReadWrite );
            qDebug() << ui->comboBoxPortName->currentText();
            my_serialPort->setBaudRate(ui->comboBoxbaudRate->currentText().toInt() );//波特率
            SetDataBit();// 设置数据位
            SetCheckBit();// 设置校验位
            SetDataFlow();// 设置流控制
            SetStopBit();// 设置停止位

            my_Timer = new QTimer(this);// 设置自动读取串口缓冲区数据时间
            connect( my_Timer, SIGNAL( timeout() ), this, SLOT(readMyCom()));
            my_Timer->start(100);//100ms读一次

            m_portopenflag = 1;

            ui->OpenPortButton->setText("关闭串口");
            ui->OpenPortButton->setChecked(true);// 使能Radio 按钮
        }

        else
        {
            m_portopenflag = 0;
            ui->OpenPortButton->setText("打开串口");
            my_serialPort->close();
        }
    }

    else
    {
        QMessageBox::warning(NULL, QString("Warning"), QString("无可用串口"));
        ui->OpenPortButton->setChecked(false);// 关闭Radio 按钮
    }
}

